package com.ben.chatroom.session;

import com.ben.chatroom.common.entity.ImUser;
import com.ben.chatroom.common.util.StringUtils;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.AttributeKey;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

/**
 * @author huangyijun
 */
@Slf4j
public class LocalSession implements ServerSession {

  @Getter
  private ImUser user;

  private final Channel channel;

  @Getter
  @Setter
  private boolean isLogin = false;
  @Getter
  private final String sessionId;

  private static final AttributeKey<String> KEY_USER_ID = AttributeKey.valueOf("key_user_id");
  public static final AttributeKey<LocalSession> SESSION_KEY = AttributeKey.valueOf("session_key");

  public LocalSession(Channel channel) {
    this.channel = channel;
    this.sessionId = StringUtils.getUUID();
  }

  /**
   * 绑定
   */
  public void bind(ImUser user) {
    this.user = user;
    log.info("LocalSession 绑定会话" + channel.remoteAddress());
    channel.attr(LocalSession.SESSION_KEY).set(this);
    this.isLogin = true;
  }

  @Override
  public void writeAndFlush(Object pkg) {
    if(channel.isWritable()) {
      channel.writeAndFlush(pkg);
    }
    else {
      log.debug("通道很忙，消息被暂存了");
      //写入消息暂存的分布式存储，如果mongo
      //等channel空闲之后，再写出去
    }
  }


  @Override
  public boolean isValid() {
    return false;
  }

  @Override
  public String getUserId() {
    return null;
  }

  //用户下线
  public synchronized void close() {
    ChannelFuture future = channel.close();
    future.addListener(new ChannelFutureListener() {
      @Override
      public void operationComplete(ChannelFuture channelFuture) throws Exception {
        if(!future.isSuccess()) {
          log.error("CHANNEL_CLOSE error");
        }
      }
    });
  }

  public static LocalSession getLocalSession(ChannelHandlerContext ctx) {
    return ctx.channel().attr(LocalSession.SESSION_KEY).get();
  }

}
